#include "client/client.hpp"
#include "client/websocket_client.hpp"

#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>

//#include <openssl/applink.c>

void test_socket_client() {
    client c;

    if (!c.connect("127.0.0.1", 1234)) {
        lwarn("client connect failed");
        return;
    }

    while (c.alive()) {
        std::string str;
        std::cin >> str;
        if (str == "close") break;
        std::vector<char> buf(str.data(), str.data() + str.length());
        if (!c.send(std::move(buf))) break;
    }
}

//
// void main1() {
//     auto ctx = my::UniquePtr<SSL_CTX>(SSL_CTX_new(TLS_client_method()));
//     if (SSL_CTX_set_default_verify_paths(ctx.get()) != 1) {
//         my::print_errors_and_exit("Error setting up trust store");
//     }
//
//     auto bio = my::UniquePtr<BIO>(BIO_new_connect("www.baidu.com:443"));
//     if (bio == nullptr) {
//         my::print_errors_and_exit("Error in BIO_new_connect");
//     }
//     if (BIO_do_connect(bio.get()) <= 0) {
//         my::print_errors_and_exit("Error in BIO_do_connect");
//     }
//     auto ssl_bio = std::move(bio) | my::UniquePtr<BIO>(BIO_new_ssl(ctx.get(), 1));
//     SSL_set_tlsext_host_name(my::get_ssl(ssl_bio.get()), "www.baidu.com");
//     SSL_set1_host(my::get_ssl(ssl_bio.get()), "www.baidu.com");
//     if (BIO_do_handshake(ssl_bio.get()) <= 0) {
//         my::print_errors_and_exit("Error in BIO_do_handshake");
//     }
//     // my::verify_ the_certificate(my::get_ssl(ssl_bio.get()), "baidu.com");
//
//     my::send_http_request(ssl_bio.get(), "GET / HTTP/1.1", "www.baidu.com");
//     std::string response = my::receive_http_message(ssl_bio.get());
//     printf("%s", response.c_str());
// }

int main() {
    logger::get_instance().set_output_file_path("./log/client");
    websocket_client c;
    if (!c.connect("127.0.0.1", 1234)) {
        lwarn("connect to websocket server failed.");
        return 0;
    }

    while (c.alive()) {
        std::string str;
        std::cin >> str;
        if (!c.alive()) {
            break;
        }
        if (str == "close") {
            c.close();
            break;
        } else if (str == "file") {
            std::cin >> str;
            if (!std::filesystem::exists(str)) {
                lwarn("cannot find file " << str);
                continue;
            }
            std::ifstream fin(str, std::ios::binary | std::ios::ate);
            std::vector<char> buf(static_cast<size_t>(fin.tellg()));
            fin.seekg(0, std::ios::beg);
            fin.read(buf.data(), buf.size());
            linfo("send file start");
            auto res = c.send_data(std::move(buf), BINARY_FRAME);
            assert(res, "send file failed");
        } else if (!c.send_data(std::vector(str.data(), str.data() + str.length()), TEXT_FRAME)) {
            lerror("send data failed");
            break;
        } else {
            linfo("send data success");
        }
    }
}